package top.yangbuyi.utils;


import com.aliyun.oss.ClientConfiguration;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.common.auth.DefaultCredentialProvider;
import com.aliyun.oss.model.CannedAccessControlList;
import com.aliyun.oss.model.OSSObject;
import com.aliyun.oss.model.PutObjectResult;
import lombok.Value;
import lombok.extern.slf4j.Slf4j;
import org.apache.tomcat.util.http.fileupload.FileItemStream;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLDecoder;
import java.util.Date;
import java.util.UUID;

/**
 * @description: 杨不易网站:www.yangbuyi.top
 * @program: yangbuyispringcloudparent
 * @ClassName: OSSUtils
 * @create: 2020-08-11 23:09
 * @author: yangbuyi
 * @since： JDK1.8
 * @OSSUtils: 另一个oss文件上传工具
 **/
@Component
@Slf4j
@ConfigurationProperties(value = "oss")
public class OSSUtils {

/**
#阿里云OSS配置
endpoint = oss-img.yangbuyi.top # 访问节点  这里表示 uri访问的图片域名相当于一个域名
bucketName = yangbuyi-img # 你创建的Bucket
picLocation = 文件夹路径 随便填  如: yangbuyi/
accessKeyId = 第一张图片要你开通的 ID
accessKeySecret = 第一张图片要你开通的 密码
 */
	//   可以自己整yml注入 看你自己
	  private static String endPoint = "";
	  private static String accessKeyId = "";
	  private static String accessKeySecret = "";
	  private static String bucketName = "";
	  private static String staticDomain = null;

	  public static void setEndPoint(String endPoint) {
			OSSUtils.endPoint = endPoint;
	  }

	  public static void setAccessKeyId(String accessKeyId) {
			OSSUtils.accessKeyId = accessKeyId;
	  }

	  public static void setAccessKeySecret(String accessKeySecret) {
			OSSUtils.accessKeySecret = accessKeySecret;
	  }

	  public static void setBucketName(String bucketName) {
			OSSUtils.bucketName = bucketName;
	  }

	  public static void setStaticDomain(String staticDomain) {
			OSSUtils.staticDomain = staticDomain;
	  }

	  public static String getStaticDomain() {
			return staticDomain;
	  }

	  public static String getEndPoint() {
			return endPoint;
	  }

	  public static String getAccessKeyId() {
			return accessKeyId;
	  }

	  public static String getAccessKeySecret() {
			return accessKeySecret;
	  }

	  public static String getBucketName() {
			return bucketName;
	  }

	  public static OSSClient getOssClient() {
			return ossClient;
	  }

	  /**
	   * oss 工具客户端
	   */
	  private static OSSClient ossClient = null;


	  /**
	   * 上传文件至阿里云 OSS
	   * 文件上传成功,返回文件完整访问路径
	   * 文件上传失败,返回 null
	   *
	   * @param file    待上传文件
	   * @param fileDir 文件保存目录
	   * @return oss 中的相对文件路径
	   */
	  public static String upload(MultipartFile file, String fileDir, String customBucket) {
			String FILE_URL = null;
			initOSS(endPoint, accessKeyId, accessKeySecret);
			StringBuilder fileUrl = new StringBuilder();
			String newBucket = bucketName;
			if (oConvertUtils.isNotEmpty(customBucket)) {
				  newBucket = customBucket;
			}
			try {
				  //判断桶是否存在,不存在则创建桶
				  if (!ossClient.doesBucketExist(newBucket)) {
						ossClient.createBucket(newBucket);
				  }
				  // 获取文件名
				  String orgName = file.getOriginalFilename();
				  if ("" == orgName) {
						orgName = file.getName();
				  }
				  // orgName = CommonUtils.getFileName(orgName);
				  System.out.println("获取文件名:" + orgName);
				  String fileName = orgName.substring(0, orgName.lastIndexOf(".")) + "_" + System.currentTimeMillis() + orgName.substring(orgName.indexOf("."));
				  if (!fileDir.endsWith("/")) {
						fileDir = fileDir.concat("/");
				  }
				  fileUrl = fileUrl.append(fileDir + fileName);

				  if (oConvertUtils.isNotEmpty(staticDomain) && staticDomain.toLowerCase().startsWith("http")) {
						FILE_URL = staticDomain + "/" + fileUrl;
				  } else {
						FILE_URL = "https://" + newBucket + "." + endPoint + "/" + fileUrl;
				  }
				  PutObjectResult result = ossClient.putObject(newBucket, fileUrl.toString(), file.getInputStream());
				  // 设置权限(公开读)
//            ossClient.setBucketAcl(newBucket, CannedAccessControlList.PublicRead);
				  if (result != null) {
						log.info("------OSS文件上传成功------" + fileUrl);
				  }
			} catch (IOException e) {
				  e.printStackTrace();
				  return null;
			}
			return FILE_URL;
	  }

	  /**
	   * 文件上传
	   *
	   * @param file
	   * @param fileDir
	   * @return
	   */
	  public static String upload(MultipartFile file, String fileDir) {
			return upload(file, fileDir, null);
	  }

	  /**
	   * 上传文件至阿里云 OSS
	   * 文件上传成功,返回文件完整访问路径
	   * 文件上传失败,返回 null
	   *
	   * @param file    待上传文件
	   * @param fileDir 文件保存目录
	   * @return oss 中的相对文件路径
	   */
	  public static String upload(FileItemStream file, String fileDir) {
			String FILE_URL = null;
			initOSS(endPoint, accessKeyId, accessKeySecret);
			StringBuilder fileUrl = new StringBuilder();
			try {
				  String suffix = file.getName().substring(file.getName().lastIndexOf('.'));
				  String fileName = UUID.randomUUID().toString().replace("-", "") + suffix;
				  if (!fileDir.endsWith("/")) {
						fileDir = fileDir.concat("/");
				  }
				  fileUrl = fileUrl.append(fileDir + fileName);

				  if (oConvertUtils.isNotEmpty(staticDomain) && staticDomain.toLowerCase().startsWith("http")) {
						FILE_URL = staticDomain + "/" + fileUrl;
				  } else {
						FILE_URL = "https://" + bucketName + "." + endPoint + "/" + fileUrl;
				  }
				  PutObjectResult result = ossClient.putObject(bucketName, fileUrl.toString(), file.openStream());
				  // 设置权限(公开读)
				  ossClient.setBucketAcl(bucketName, CannedAccessControlList.PublicRead);
				  if (result != null) {
						log.info("------OSS文件上传成功------" + fileUrl);
				  }
			} catch (IOException e) {
				  e.printStackTrace();
				  return null;
			}
			return FILE_URL;
	  }

	  /**
	   * 删除文件
	   *
	   * @param url
	   */
	  public static void deleteUrl(String url) {
			deleteUrl(url, null);
	  }

	  /**
	   * 删除文件
	   *
	   * @param url
	   */
	  public static void deleteUrl(String url, String bucket) {
			String newBucket = bucketName;
			if (oConvertUtils.isNotEmpty(bucket)) {
				  newBucket = bucket;
			}
			String bucketUrl = "";
			if (oConvertUtils.isNotEmpty(staticDomain) && staticDomain.toLowerCase().startsWith("http")) {
				  bucketUrl = staticDomain + "/";
			} else {
				  bucketUrl = "https://" + newBucket + "." + endPoint + "/";
			}
			url = url.replace(bucketUrl, "");
			ossClient.deleteObject(newBucket, url);
	  }

	  /**
	   * 删除文件
	   *
	   * @param fileName
	   */
	  public static void delete(String fileName) {
			ossClient.deleteObject(bucketName, fileName);
	  }

	  /**
	   * 获取文件流
	   *
	   * @param objectName
	   * @param bucket
	   * @return
	   */
	  public static InputStream getOssFile(String objectName, String bucket) {
			InputStream inputStream = null;
			try {
				  String newBucket = bucketName;
				  if (oConvertUtils.isNotEmpty(bucket)) {
						newBucket = bucket;
				  }
				  initOSS(endPoint, accessKeyId, accessKeySecret);
				  OSSObject ossObject = ossClient.getObject(newBucket, objectName);
				  inputStream = new BufferedInputStream(ossObject.getObjectContent());
			} catch (Exception e) {
				  log.info("文件获取失败" + e.getMessage());
			}
			return inputStream;
	  }

	  /**
	   * 获取文件流
	   *
	   * @param objectName
	   * @return
	   */
	  public static InputStream getOssFile(String objectName) {
			return getOssFile(objectName, null);
	  }

	  /**
	   * 获取文件外链
	   *
	   * @param bucketName
	   * @param objectName
	   * @param expires
	   * @return
	   */
	  public static String getObjectURL(String bucketName, String objectName, Date expires) {
			initOSS(endPoint, accessKeyId, accessKeySecret);
			try {
				  if (ossClient.doesObjectExist(bucketName, objectName)) {
						URL url = ossClient.generatePresignedUrl(bucketName, objectName, expires);
						return URLDecoder.decode(url.toString(), "UTF-8");
				  }
			} catch (Exception e) {
				  log.info("文件路径获取失败" + e.getMessage());
			}
			return null;
	  }

	  /**
	   * 初始化 oss 客户端
	   *
	   * @return
	   */
	  private static OSSClient initOSS(String endpoint, String accessKeyId, String accessKeySecret) {
			if (ossClient == null) {
				  ossClient = new OSSClient(endpoint,
						  new DefaultCredentialProvider(accessKeyId, accessKeySecret),
						  new ClientConfiguration());
			}
			return ossClient;
	  }


	  /**
	   * 上传文件到oss
	   *
	   * @param stream
	   * @param relativePath
	   * @return
	   */
	  public static String upload(InputStream stream, String relativePath) {
			String FILE_URL = null;
			String fileUrl = relativePath;
			initOSS(endPoint, accessKeyId, accessKeySecret);
			if (oConvertUtils.isNotEmpty(staticDomain) && staticDomain.toLowerCase().startsWith("http")) {
				  FILE_URL = staticDomain + "/" + relativePath;
			} else {
				  FILE_URL = "https://" + bucketName + "." + endPoint + "/" + fileUrl;
			}
			PutObjectResult result = ossClient.putObject(bucketName, fileUrl.toString(), stream);
			// 设置权限(公开读)
			ossClient.setBucketAcl(bucketName, CannedAccessControlList.PublicRead);
			if (result != null) {
				  log.info("------OSS文件上传成功------" + fileUrl);
			}
			return FILE_URL;
	  }


}
